﻿using System.Text.RegularExpressions;

namespace LS.Screening.Core
{
    /// <summary>
    /// 身份证扩展方法
    /// </summary>
    public static class IdentityCardExtension
    {
        /// <summary>
        /// 判断是否为身份证号码
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        public static bool CheckIsSuccess(this string cardId)
        {
            if (string.IsNullOrEmpty(cardId)) return false;
            Regex regex1 = new Regex("^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$");
            Regex regex2 = new Regex(@"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$");
            if (!regex1.IsMatch(cardId) && !regex2.IsMatch(cardId))
                return false;
            if (IsMatch(cardId) == "身份证验证成功" || regex1.IsMatch(cardId))
                return true;
            return false;
        }

        /// <summary>
        /// 检测18位身份证号码
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        private static string IsMatch(string cardId)
        {
            string pattern = @"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$";
            string birth = cardId.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            // 加权数组,用于验证最后一位的校验数字
            int[] arr_weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            // 最后一位计算出来的校验数组，如果不等于这些数字将不正确
            string[] id_last = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
            int sum = 0;
            //通过循环前16位计算出最后一位的数字
            for (int i = 0; i < 17; i++)
            {
                sum += arr_weight[i] * int.Parse(cardId[i].ToString());
            }
            // 实际校验位的值
            int result = sum % 11;
            // 首先18位格式检查
            if (Regex.IsMatch(cardId, pattern))
            {   // 出生日期检查
                if (DateTime.TryParse(birth, out time))
                {
                    // 校验位检查
                    if (id_last[result] == cardId[17].ToString())
                    {
                        return "身份证验证成功";
                    }
                    else
                    {
                        return "身份证最后一位校验错误";
                    }
                }
                else
                {
                    return "出生日期验证失败";
                }
            }
            else
            {
                return "身份证号格式错误";
            }
        }

        /// <summary>
        /// 截取出身年月日
        /// </summary>
        /// <param name="IDCard">身份证号</param>
        /// <returns></returns>
        public static DateTime? GetDate(this string idCard)
        {
            //身份证校验 
            if (!idCard.CheckIsSuccess())
                return null;
            DateTime? birthday = null;
            int year;
            int month;
            int day;
            if (idCard.Length == 15)
            {
                year = int.Parse(idCard.Substring(6, 2));
                month = int.Parse(idCard.Substring(8, 2));
                day = int.Parse(idCard.Substring(10, 2));
                birthday = new DateTime(year, month, day);
            }
            if (idCard.Length == 18)
            {
                year = int.Parse(idCard.Substring(6, 4));
                month = int.Parse(idCard.Substring(10, 2));
                day = int.Parse(idCard.Substring(12, 2));
                birthday = new DateTime(year, month, day);
            }
            return birthday;
        }
    }
}
